package it.gestionedocumentale.struts.action.upload;

import java.io.File;
import java.io.FileOutputStream;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

import it.gestionedocumentale.model.Classificazione;
import it.gestionedocumentale.model.Documento;
import it.gestionedocumentale.model.Gruppo;
import it.gestionedocumentale.model.Tag;
import it.gestionedocumentale.model.Utente;
import it.gestionedocumentale.spring.service.MyServiceFactory;
import it.gestionedocumentale.struts.form.DocumentoForm;
import it.gestionedocumentale.utility.UtilityDate;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.struts.action.ActionForm;
import org.apache.struts.action.ActionForward;
import org.apache.struts.action.ActionMapping;
import org.apache.struts.actions.DispatchAction;
import org.hibernate.HibernateException;

public class ConfermaUploadDocumentoAction extends DispatchAction {
	
	private static Log log = LogFactory.getLog(ConfermaUploadDocumentoAction.class);
	
	@Override
	protected ActionForward dispatchMethod(ActionMapping mapping, ActionForm form,
			HttpServletRequest request, HttpServletResponse response, String arg4)
			throws Exception {
		
		Utente utenteSession = (Utente) request.getSession().getAttribute("utenteSession");
		if(utenteSession == null) {
			return mapping.findForward("notInSession");
		}
		
		return super.dispatchMethod(mapping, form, request, response, arg4);
	}
	
	
	public ActionForward caricaClassificazione(ActionMapping mapping, ActionForm form,
			HttpServletRequest request, HttpServletResponse response)
			throws Exception {
		
		DocumentoForm documentoForm = (DocumentoForm) form;
		Long idClassificazioneSelected = documentoForm.getIdClassificazione();
		
		@SuppressWarnings("unchecked")
		List<Classificazione> listaSelezioneClass = 
				(List<Classificazione>) request.getSession().getAttribute("listaSelezioneClass");
		
		Classificazione classificazione = new Classificazione();
		List<Classificazione> listaClassificazioni = new ArrayList<Classificazione>();
		List<Gruppo> listaGruppi = new ArrayList<Gruppo>();
		List<Tag> listaTag = new ArrayList<Tag>();
		List<Utente> listaUtenti = new ArrayList<Utente>();
		
		try {
			if(documentoForm.getIdClassificazione() != null && documentoForm.getIdClassificazione() != 0){
				// classificazione caricata dal db con id selezionato
				classificazione = MyServiceFactory.getClassificazioneService().findById(idClassificazioneSelected);
				// aggiuta della classificazione alla lista di classificazioni selezionate
				listaSelezioneClass.add(classificazione);
			}
			
			// ******************** lista di classificazione del DB ********************
			listaClassificazioni = MyServiceFactory.getClassificazioneService().findAll();
			
			// ******************** lista gruppi dal DB ********************
		    listaGruppi = MyServiceFactory.getGruppoService().findAll();
		    
		    // ******************** lista di tag dal DB ********************
		    listaTag = MyServiceFactory.getTagService().findAll();
		    
		    // ******************** lista di utenti dal DB ********************
		    listaUtenti = MyServiceFactory.getUtenteService().findAllActive();
			
			// rimozione dalla lista della classificazione selezionata
			listaClassificazioni.removeAll(listaSelezioneClass);
			
		} catch (Exception e) {
			e.printStackTrace();
			log.error(e);
			return mapping.findForward("error");
		}
	    
	    if(listaClassificazioni.size()==0){
	    	listaClassificazioni=null;
	    }
	    
	    request.getSession().setAttribute("listaSelezioneClass", listaSelezioneClass);
		request.setAttribute("listaClassificazioni", listaClassificazioni);
		request.setAttribute("listaGruppi", listaGruppi);
	    request.setAttribute("listaTag", listaTag);
	    request.setAttribute("listaUtenti", listaUtenti);
	    return mapping.findForward("back");
	}
	
	public ActionForward rimuoviClassificazione(ActionMapping mapping, ActionForm form,
			HttpServletRequest request, HttpServletResponse response)
			throws Exception {
		
		@SuppressWarnings("unchecked")
		List<Classificazione> listaSelezioneClass = 
			(List<Classificazione>) request.getSession().getAttribute("listaSelezioneClass");
		
		Long idToRemove = Long.parseLong(request.getParameter("idToRemove"));
		List<Classificazione> listaClassificazioni = new ArrayList<Classificazione>();
		List<Gruppo> listaGruppi = new ArrayList<Gruppo>();
		List<Tag> listaTag = new ArrayList<Tag>();
		List<Utente> listaUtenti = new ArrayList<Utente>();
		
		Classificazione classificazioneToRemove = new Classificazione();
		classificazioneToRemove.setIdClassificazione(idToRemove);
		
	    try {
			// per deselezionare la classificazione
	    	listaSelezioneClass.remove(classificazioneToRemove);
			
			// ******************** lista di classificazione del DB ********************
			listaClassificazioni = MyServiceFactory.getClassificazioneService().findAll();
			
			// ******************** lista gruppi dal DB ********************
		    listaGruppi = MyServiceFactory.getGruppoService().findAll();
		    
		    // ******************** lista di tag dal DB ********************
		    listaTag = MyServiceFactory.getTagService().findAll();
		    
		    // ******************** lista di utenti dal DB ********************
		    listaUtenti = MyServiceFactory.getUtenteService().findAllActive();
			
			// for che rimuovere le classificazioni gia selezionate
			listaClassificazioni.removeAll(listaSelezioneClass);
			
		} catch (Exception e) {
			e.printStackTrace();
			log.error(e);
			return mapping.findForward("error");
		}
	    
		if(listaClassificazioni.size()==0){
	    	listaClassificazioni=null;
	    }
		
	    request.setAttribute("listaClassificazioni", listaClassificazioni);
	    request.setAttribute("listaGruppi", listaGruppi);
	    request.setAttribute("listaTag", listaTag);
	    request.setAttribute("listaUtenti", listaUtenti);
		request.getSession().setAttribute("listaSelezioneClass", listaSelezioneClass);
		return mapping.findForward("back");
	    
	}
	
	public ActionForward confermaUpload(ActionMapping mapping, ActionForm form,
			HttpServletRequest request, HttpServletResponse response)
			throws Exception {
		
		DocumentoForm documentoForm = (DocumentoForm) form;
		
		@SuppressWarnings("unchecked")
		List<Classificazione> listaSelezioneClass = 
				(List<Classificazione>) request.getSession().getAttribute("listaSelezioneClass");
		
		if(documentoForm.getIdClassificazione() != null && documentoForm.getIdClassificazione() != 0){
			Long idClassificazioneSelected = documentoForm.getIdClassificazione();
			Classificazione classificazione = 
					MyServiceFactory.getClassificazioneService().findById(idClassificazioneSelected);
			
			listaSelezioneClass.add(classificazione);
		}
		
		
		byte[] arrayByte = (byte[])request.getSession().getAttribute("arrayByte");
        String fileName = documentoForm.getNome();
        // path assoluto della cartella sul file system in cui vengono caricati i file
		String filePath = "/home/gestdoc/Documenti/file-upload/";
		File fileToCreate = new File(filePath, fileName);
	    
	    try {
	    	if(!documentoForm.getNome().equals("") && !fileToCreate.exists()){
					// crea outputStream del file
					FileOutputStream fileOutStream = new FileOutputStream(fileToCreate);
					
					// scrive nell'outputStream l'array di byte
				    fileOutStream.write(arrayByte);
				    
				    // pulisce e chiude outputStream
				    fileOutStream.flush();
				    fileOutStream.close();
	    	}
	    	
	    	//metodo che salva il documento sul DB
	    	salvaDocumento(request, documentoForm);
		}
	    catch (HibernateException e) {
	    	e.printStackTrace();
	    	fileToCreate.delete();
	    	log.error(e);
	    	return mapping.findForward("error");
		}
	    catch (Exception e) {
			e.printStackTrace();
			log.error(e);
			return mapping.findForward("error");
		}
	    
	    request.getSession().removeAttribute("arrayByte");
	    request.getSession().removeAttribute("listaSelezioneClass");
	    request.setAttribute("message", "File salvato con successo");
	    
	    String dataCaricamento = new String();
		dataCaricamento = UtilityDate.getDateAsString(UtilityDate.today(), "dd/MM/yyyy HH:mm:ss.SSS");
	    
	    log.info("File caricato da: "+request.getSession().getAttribute("utenteSession") 
	    		+"\n il giorno: "+ dataCaricamento
	    		+"\n Nome file: "+ documentoForm.getNome());
	    
	    return mapping.findForward("ok");
	}
	
	
	private void salvaDocumento(HttpServletRequest request, DocumentoForm documentoForm) throws Exception{
		
		int i=0;
		Documento documento = new Documento();
		
		@SuppressWarnings("unchecked")
		List<Classificazione> listaSelezioneClass = 
				(List<Classificazione>) request.getSession().getAttribute("listaSelezioneClass");
		Set<Classificazione> listaClassificazione = new HashSet<Classificazione>();
		
		int[] arrayTags = documentoForm.getTags();
		Set<Tag> listaTags = new HashSet<Tag>();
		
		int[] arrayGruppi = documentoForm.getGruppi();
		Set<Gruppo> listaGruppi = new HashSet<Gruppo>();
		
		int[] arrayUtenti = documentoForm.getUtenti();
		Set<Utente> listaUtenti = new HashSet<Utente>();
		
		for (i=0; i<listaSelezioneClass.size(); i++){
			listaClassificazione.add(listaSelezioneClass.get(i));
		}
		
		if(arrayTags != null && arrayTags.length > 0){
			for (i=0; i<arrayTags.length; i++){
				Long idTag = (long) arrayTags[i];
				Tag tag = new Tag();
				tag = MyServiceFactory.getTagService().findById(idTag);
				listaTags.add(tag);
			}
		}
		
		if(arrayGruppi != null && arrayGruppi.length > 0){
			for (i=0; i<arrayGruppi.length; i++){
				Long idGruppo = (long) arrayGruppi[i];
				Gruppo gruppo = new Gruppo();
				gruppo = MyServiceFactory.getGruppoService().findById(idGruppo);
				listaGruppi.add(gruppo);
			}
		}
		
		if(arrayUtenti != null && arrayUtenti.length > 0){
			for (i=0; i<arrayUtenti.length; i++){
				Long idUtente = (long) arrayUtenti[i];
				Utente utente = new Utente();
				utente = MyServiceFactory.getUtenteService().findById(idUtente);
				listaUtenti.add(utente);
			}
		}
		
		documento.setUtenteCreatore((Utente) request.getSession().getAttribute("utenteSession"));
		documento.setNomeDocumento(documentoForm.getNome());
		documento.setPath("/home/gestdoc/Documenti/file-upload/");
		documento.setDataUpload(UtilityDate.today());
		documento.setSize(documentoForm.getSize());
		documento.setListaClassificazioni(listaClassificazione);
		documento.setListaTag(listaTags);
		documento.setListaGruppi(listaGruppi);
		documento.setListaUtenti(listaUtenti);
		
		MyServiceFactory.getDocumentoService().save(documento);
		
	}

}
